﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Text;
using System.Configuration;
using DFCLib;
using System.Diagnostics;

namespace dctmMiddleService
{


    // NOTE: If you change the class name "Service1" here, you must also update the reference to "Service1" in Web.config and in the associated .svc file.
    public class DctmMiddleService : IDctmMiddleService, IDisposable
    {

        private String dctmUser = null;
        private String dctmPassword = null;
        private String repository = null;

        private static IDfSession session = null;
        private static String dfcVersion = null;
        private String errorMessage = null;
        private static DfClientX _clientx = null;
        private static IDfClient _client = null;

        private const int READ_QUERY = 0;
        private const int QUERY = 1;
        private const int CACHE_QUERY = 2;
        private const int EXECUTE_QUERY = 3;
        private const int EXECUTE_READ_QUERY = 4;
        private const int APPLY = 5;

        TraceSwitch serviceSwitch = null;

        public DctmMiddleService()
        {
            serviceSwitch = new TraceSwitch("General", "General");

            Trace.WriteLine("DctmMiddleService() constructor called.");

            dctmUser = ConfigurationManager.AppSettings["DctmUser"];
            if (String.IsNullOrEmpty(dctmUser))
            {
                dctmUser = "damadmin";
            }
            dctmPassword = ConfigurationManager.AppSettings["DctmPassword"];
            if (String.IsNullOrEmpty(dctmPassword))
            {
                dctmPassword = "Nov122008";
            }
            repository = ConfigurationManager.AppSettings["Repository"];
            if (String.IsNullOrEmpty(repository))
            {
                repository = "damdev";
            }

            if (null == session)
            {
                session = getDctmSession();

            }


        }

        protected IDfSession getDctmSession()
        {
            Trace.WriteLineIf(serviceSwitch.TraceInfo, "getDctmSession() called.");

            if (null == _clientx)
            {
                _clientx = new DfClientX();
            }
            if (null == _client)
            {
                _client = _clientx.getLocalClient();
            }

            if (_client == null)
            {
                Trace.WriteLine("Failed to instantiate Documentum client.");
                throw new Exception("Failed creating Documentum client");
            }

            dfcVersion = _clientx.getDFCVersion();
            Trace.WriteLine("DFC version = " + dfcVersion);

            // Create an object with the credentials of the user
            IDfLoginInfo _loginInfoObj = _clientx.getLoginInfo();
            _loginInfoObj.setUser(dctmUser);
            _loginInfoObj.setPassword(dctmPassword);

            // Create a new session to the requested DocBase
            session = _client.newSession(repository, _loginInfoObj);

            if (session == null || !session.isConnected())
            {
                errorMessage = "Failed conecting to Documentum";

                if (session != null)
                {
                    errorMessage = session.getMessage(1);
                }

                Trace.WriteLine("Error message generated: " + errorMessage);
            }

            Trace.WriteLineIf(serviceSwitch.TraceInfo, "Valid DFC session returned.");

            return session;

        }

        public string GetData(int value)
        {
            return string.Format("You entered: {0}", value);
        }

        public CompositeType GetDataUsingDataContract(CompositeType composite)
        {
            if (composite.BoolValue)
            {
                composite.StringValue += "Suffix";
            }
            return composite;
        }


        public void setValueAssistanceList(ValueAssistance[] p_list, String customType, String customAttribute)
        {
            Trace.WriteLine("setValueAssistanceList() called.");


            StringBuilder valueListBuilder = new StringBuilder();
            StringBuilder mappingTableBuilder = new StringBuilder();

            try
            {
                if (null == session)
                {
                    Trace.WriteLine("Determined session is NULL.");
                    session = getDctmSession();

                }

                Trace.WriteLineIf(serviceSwitch.TraceInfo, "Determined a session exists and using it.");
                IDfQuery queryBuilder = _clientx.getQuery();
                Trace.WriteLineIf(serviceSwitch.TraceInfo, "Got query interface from client object.");
                String commonDqlPiece = "ALTER TYPE " + customType + " MODIFY (" + customAttribute + " (";
                String valueAssistancePiece = "VALUE ASSISTANCE IS LIST(";
                int numOfValueAssistanceObjects = p_list.Count();

                for (int i = 0; i < numOfValueAssistanceObjects; i++)
                {
                    valueListBuilder.Append(p_list[i].Value);
                    mappingTableBuilder.Append("VALUE=");
                    mappingTableBuilder.Append(p_list[i].Value);
                    mappingTableBuilder.Append(" DISPLAY='");
                    mappingTableBuilder.Append(p_list[i].DisplayString);
                    mappingTableBuilder.Append("'");

                    if (i < numOfValueAssistanceObjects - 1)
                    {
                        valueListBuilder.Append(", ");
                        mappingTableBuilder.Append(", ");
                    }

                }

                String endOfQuery = ") IS COMPLETE)) PUBLISH";
                String dqlStr = commonDqlPiece + valueAssistancePiece + valueListBuilder.ToString() + endOfQuery;
                Trace.WriteLineIf(serviceSwitch.TraceInfo, "Completed DQL query: " + dqlStr);
                queryBuilder.setDQL(dqlStr);
                Trace.WriteLineIf(serviceSwitch.TraceInfo, "Query string set for altering value assistance list.");
                queryBuilder.execute(session, QUERY);
                Trace.WriteLineIf(serviceSwitch.TraceInfo, "Executed query to alter value assistance list.");

                String mappingTablePiece = "MAPPING TABLE (";
                endOfQuery = "))) PUBLISH";

                dqlStr = commonDqlPiece + mappingTablePiece + mappingTableBuilder.ToString() + endOfQuery;
                Trace.WriteLineIf(serviceSwitch.TraceInfo, "Completed DQL query: " + dqlStr);
                queryBuilder.setDQL(dqlStr);
                Trace.WriteLineIf(serviceSwitch.TraceInfo, "Query string set for altering value assistance mappings.");
                queryBuilder.execute(session, QUERY);
                Trace.WriteLineIf(serviceSwitch.TraceInfo, "Executed query to alter value assistance mappings.");



            }
            catch (Exception e)
            {
                String msg = e.Message;
                String stacktrace = e.StackTrace;
                Trace.WriteLine("Exception caught in setCurrentValueAssistanceList().");
                Trace.WriteLine(msg);
                Trace.WriteLine(stacktrace);

            }

            Trace.WriteLine("setValueAssistanceList() ran as expected.");


        }

        public void Dispose()
        {
            Trace.Flush();
            Trace.Close();
        }

        public List<ValueAssistance> GetCurrentValueAssistanceList(String customType, String customAttribute)
        {

            Trace.WriteLine("GetCurrentValueAssistanceList() called.");

            List<ValueAssistance> retList = null;

            try
            {
                if (null == session)
                {
                    Trace.WriteLine("Determined session is NULL.");
                    session = getDctmSession();

                }

                IDfId policyId = null;
                //policyId = session.getIdByQualification(String.Empty);

                Trace.WriteLineIf(serviceSwitch.TraceInfo, "Determined a session exists and using it.");
                IDfType dctmCustomType = session.getType(customType);

                if (null != dctmCustomType)
                {
                    Trace.WriteLineIf(serviceSwitch.TraceInfo, "Got custom type: " + customType);
                }
                else
                {
                    Trace.WriteLine("No custom type returned.");
                }



                IDfValidator validator = dctmCustomType.getTypeValidator(policyId, String.Empty);
                //IDfValidator validator = dctmCustomType.getValidator();
                Trace.WriteLineIf(serviceSwitch.TraceInfo, "Extracted validator from IDfType.");
                IDfValueAssistance valueAssistance = validator.getValueAssistance(customAttribute, null);
                Trace.WriteLineIf(serviceSwitch.TraceInfo, "Extracted IDfValueAssistance from validator.");

                IDfList displayList = valueAssistance.getDisplayValues();
                Trace.WriteLineIf(serviceSwitch.TraceInfo, "Got list of display values in value assistance for attribute: " + customAttribute);
                IDfList valueList = valueAssistance.getActualValues();
                Trace.WriteLineIf(serviceSwitch.TraceInfo, "Got list of actual values in value assistance.");

                if (displayList.getCount() != valueList.getCount())
                {
                    Trace.WriteLine("Error in value assistance list.");
                    return null;
                }

                Int32 totalValues = valueList.getCount();
                Trace.WriteLineIf(serviceSwitch.TraceInfo, "Found " + totalValues + " in value assistance list.");

                retList = new List<ValueAssistance>(totalValues);
                Trace.WriteLineIf(serviceSwitch.TraceInfo, "Initializing generic List to hold value assistance.");

                for (int i = 0; i < totalValues; i++)
                {
                    ValueAssistance obj = new ValueAssistance();
                    Trace.WriteLineIf(serviceSwitch.TraceInfo, "Created ValueAssistance data contract.");
                    obj.DisplayString = displayList.getString(i);
                    Trace.WriteLineIf(serviceSwitch.TraceInfo, "Adding display string: " + obj.DisplayString);
                    obj.Value = valueList.getString(i);
                    Trace.WriteLineIf(serviceSwitch.TraceInfo, "Adding value string: " + obj.Value);
                    retList.Add(obj);
                    Trace.WriteLineIf(serviceSwitch.TraceInfo, "Value assistance object added to list.");
                }


            }
            catch (Exception e)
            {
                String msg = e.Message;
                String stacktrace = e.StackTrace;
                Trace.WriteLine("Exception caught in GetCurrentValueAssistanceList().");
                Trace.WriteLine(msg);
                Trace.WriteLine(stacktrace);

            }

            Trace.WriteLine("GetCurrentValueAssistanceList() ran as expected.");

            return retList;
        }



    }
}
